#include "barrier.h"

int barrier_init(barrier_t* barrier) {
    int check=0;

	pthread_mutexattr_t attr;

	assert(barrier != NULL);

	if(barrier == NULL) {
		return -1;
	}
	barrier=(barrier_t*) malloc(sizeof(struct sBarrier));

	barrier->arrived=0;
	pthread_mutexattr_init(&attr);
	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
	check=pthread_mutex_init(&barrier->barrierLock, &attr);
	pthread_mutexattr_destroy(&attr); // TODO: check if we do need to destroy the attr after init.

    pthread_cond_init(&barrier->reachedNumOfThreads, NULL);

    return check;
    }


void barrier_destroy(barrier_t* barrier) {

	assert(barrier != NULL);

	if(barrier == NULL) {
		return;
	}

	pthread_mutex_destroy(&barrier->barrierLock);
	pthread_cond_destroy(&barrier->reachedNumOfThreads);
}

int barrier(barrier_t* barrier) {

	assert(barrier != NULL);

	if(barrier == NULL) {
		return -1;
	}

    pthread_mutex_lock(&barrier->barrierLock);

    while(!barrier->arrived) {
    	pthread_cond_wait(&barrier->reachedNumOfThreads, &barrier->barrierLock);
    }

    pthread_mutex_lock(&barrier->barrierLock);
    return 0;
}
